home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 428_02 / libsrc / listbox.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-13  |  5.0 KB  |  221 lines

  1. /*
  2. ** listbox.c
  3. **
  4. ** Pictor, Version 1.51, Copyright (c) 1992-94 SoftCircuits
  5. ** Redistributed by permission.
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include "pictor.h"
  11.  
  12. #define UPDATE_NOUPDATE 0
  13. #define UPDATE_CURSOR   1
  14. #define UPDATE_WINDOW   2
  15.  
  16. int _PL_lbcolwidth = 12;
  17. int _PL_lbrows = 8;
  18. int _PL_lbcols = 4;
  19.  
  20.  
  21. /*
  22. ** Allows the user to select from a list of items using the cursor
  23. ** keys. TRUE is returned and *selection is set to the index of the
  24. ** selected item if the user pressed Enter. FALSE is returned and
  25. ** *selection is unchanged if Escape is pressed or numitems == 0.
  26. **
  27. ** This function could be called recursively if it is active and
  28. ** help is selected.
  29. */
  30. int listbox(char **items,int numitems,int *selection,
  31.     char *title,COLORSTRUCT *colors)
  32. {
  33.     int done = FALSE,update = UPDATE_WINDOW,leftcol = 0;
  34.     int i,j,key,top,left,row,col,newsel,oldsel = 0;
  35.  
  36.     newsel = *selection;
  37.  
  38.     if(numitems == 0)
  39.         return(FALSE);
  40.  
  41.     top = center(_PL_lbrows + 2,_PL_rows);
  42.     left = center((_PL_lbcols * (_PL_lbcolwidth + 2)) + 2,_PL_columns);
  43.  
  44.     wopen(top,left,_PL_lbrows + 2,(_PL_lbcols * (_PL_lbcolwidth + 2)) + 2,
  45.         colors->normal,WO_STATICMEM | WO_SHADOW);
  46.     wtitle(title);
  47.  
  48.     while(!done) {
  49.  
  50.         if(update != UPDATE_NOUPDATE) {
  51.  
  52.             if((newsel / _PL_lbrows) < leftcol) {
  53.                 leftcol = (newsel / _PL_lbrows);
  54.                 update = UPDATE_WINDOW;
  55.             }
  56.             else if((newsel / _PL_lbrows) >= (leftcol + _PL_lbcols)) {
  57.                 leftcol = (newsel / _PL_lbrows) - (_PL_lbcols - 1);
  58.                 update = UPDATE_WINDOW;
  59.             }
  60.  
  61.             if(update == UPDATE_WINDOW) {
  62.  
  63.                 vcolor(colors->normal);
  64.                 i = (leftcol * _PL_lbrows);
  65.  
  66.                 for(col = 0;col < _PL_lbcols;col++) {
  67.                     for(row = 0;row < _PL_lbrows;row++,i++) {
  68.                         setwpos(row + 1,(col * (_PL_lbcolwidth + 2)) + 1);
  69.                         if(i < numitems) {
  70.                             wputc(' ');
  71.                             for(j = 0;j < _PL_lbcolwidth && items[i][j];j++) {
  72.                                 wputc(items[i][j]);
  73.                             }
  74.                             wrepc(' ',(_PL_lbcolwidth + 1) - j);
  75.                         }
  76.                         else {
  77.                             wrepc(' ',_PL_lbcolwidth + 2);
  78.                         }
  79.                     }
  80.                 }
  81.             }
  82.             else {
  83.                 /* unhilight old selection */
  84.                 i = ((oldsel / _PL_lbrows) - leftcol);
  85.                 setwpos((oldsel % _PL_lbrows) + 1,(i * (_PL_lbcolwidth + 2)) + 1);
  86.                 wrepa(colors->normal,_PL_lbcolwidth + 2);
  87.             }
  88.  
  89.             /* hilight new selection */
  90.             i = ((newsel / _PL_lbrows) - leftcol);
  91.             setwpos((newsel % _PL_lbrows) + 1,(i * (_PL_lbcolwidth + 2)) + 1);
  92.             wrepa(colors->select,_PL_lbcolwidth + 2);
  93.  
  94.             update = UPDATE_NOUPDATE;
  95.             oldsel = newsel;
  96.         }
  97.         switch(key = kbdread()) {
  98.             case ENTER_KEY:
  99.                 *selection = newsel;
  100.                 done = TRUE;
  101.                 break;
  102.             case ESCAPE_KEY:
  103.                 done = TRUE;
  104.                 break;
  105.             case UP_KEY:
  106.                 if(newsel > 0) {
  107.                     newsel--;
  108.                     update = UPDATE_CURSOR;
  109.                 }
  110.                 else beep();
  111.                 break;
  112.             case DOWN_KEY:
  113.             case SPACE_BAR:
  114.                 if(newsel < (numitems - 1)) {
  115.                     newsel++;
  116.                     update = UPDATE_CURSOR;
  117.                 }
  118.                 else beep();
  119.                 break;
  120.             case LEFT_KEY:
  121.                 if(newsel > 0) {
  122.                     if(newsel > _PL_lbrows) {
  123.                         newsel -= _PL_lbrows;
  124.                     }
  125.                     else {
  126.                         newsel = 0;
  127.                     }
  128.                     update = UPDATE_CURSOR;
  129.                 }
  130.                 else beep();
  131.                 break;
  132.             case RIGHT_KEY:
  133.                 if(newsel < (numitems - 1)) {
  134.                     if(newsel < (numitems - _PL_lbrows)) {
  135.                         newsel += _PL_lbrows;
  136.                     }
  137.                     else {
  138.                         newsel = (numitems - 1);
  139.                     }
  140.                     update = UPDATE_CURSOR;
  141.                 }
  142.                 else beep();
  143.                 break;
  144.             case PGUP_KEY:
  145.                 if(newsel > 0) {
  146.                     if(newsel > (_PL_lbrows * _PL_lbcols)) {
  147.                         newsel -= (_PL_lbrows * _PL_lbcols);
  148.                         if(leftcol > _PL_lbcols)
  149.                             leftcol -= _PL_lbcols;
  150.                         else
  151.                             leftcol = 0;
  152.                         update = UPDATE_WINDOW;
  153.                     }
  154.                     else {
  155.                         newsel = 0;
  156.                         update = UPDATE_CURSOR;
  157.                     }
  158.                 }
  159.                 else beep();
  160.                 break;
  161.             case PGDN_KEY:
  162.                 if(newsel < (numitems - 1)) {
  163.                     if(newsel < (numitems - (_PL_lbrows * _PL_lbcols))) {
  164.                         newsel += (_PL_lbrows * _PL_lbcols);
  165.                         leftcol += _PL_lbcols;
  166.                         update = UPDATE_WINDOW;
  167.                     }
  168.                     else {
  169.                         newsel = (numitems - 1);
  170.                         update = UPDATE_CURSOR;
  171.                     }
  172.                 }
  173.                 else beep();
  174.                 break;
  175.             case HOME_KEY:
  176.                 if(newsel > 0) {
  177.                     newsel = 0;
  178.                     update = UPDATE_CURSOR;
  179.                 }
  180.                 break;
  181.             case END_KEY:
  182.                 if(newsel < (numitems - 1)) {
  183.                     newsel = (numitems - 1);
  184.                     update = UPDATE_CURSOR;
  185.                 }
  186.                 break;
  187.             case F1_KEY:
  188.                 if(_PL_helpfunc != NULL)
  189.                     _PL_helpfunc(_PL_helpcontext);
  190.                 else beep();
  191.                 break;
  192.             default:
  193.                 /* jump to selection if first letter pressed */
  194.                 kbdflush();
  195.                 key = toupper(key & 0xFF);
  196.                 if(isalnum(key)) {
  197.                     for(i = newsel + 1;i < numitems && !update;i++) {
  198.                         if(key == toupper(*items[i])) {
  199.                             newsel = i;
  200.                             update = UPDATE_CURSOR;
  201.                         }
  202.                     }
  203.                     for(i = 0;i <= newsel && !update;i++) {
  204.                         if(key == toupper(*items[i])) {
  205.                             newsel = i;
  206.                             update = UPDATE_CURSOR;
  207.                         }
  208.                     }
  209.                 }
  210.                 if(!update)
  211.                     beep();
  212.                 break;
  213.         }
  214.     }
  215.     wclose();
  216.  
  217.     /* return TRUE if enter pressed */
  218.     return(key == ENTER_KEY);
  219.  
  220. } /* listbox */
  221.